package com.bbcare.followup.plat.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import com.bbcare.comm.AppException;
import com.bbcare.comm.ToolUtil;
import com.bbcare.comm.ToolUtils;
import com.bbcare.department.plat.service.IDepartmentBasicService;
import com.bbcare.followup.plat.dto.bo.MilkPatientComparator;
import com.bbcare.followup.plat.dto.bo.PatientListBO;
import com.bbcare.followup.plat.dto.request.*;
import com.bbcare.followup.plat.dto.response.FuMilkPreparationRecordResDTO;
import com.bbcare.followup.plat.entity.FuMilkPreparationRecord;
import com.bbcare.followup.plat.entity.PatientQueueScheme;
import com.bbcare.followup.plat.service.IFuMilkPreparationRecordService;
import com.bbcare.followup.plat.service.IMessageNotifyRecordService;
import com.bbcare.followup.plat.store.ibatis.IFuMilkPreparationRecordDAO;
import com.bbcare.followup.plat.store.ibatis.IPatientDAO;
import com.bbcare.followup.plat.store.ibatis.IPatientQueueSchemeDAO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 预约记录服务实现
 */
@Service
public class FuMilkPreparationRecordServiceImpl implements IFuMilkPreparationRecordService {
    private static final Log logger = LogFactory.getLog(FuMilkPreparationRecordServiceImpl.class);

    @Autowired
    private IFuMilkPreparationRecordDAO fuMilkPreparationRecordDAO;

    @Autowired
    private IPatientDAO patientDao;

    @Autowired
    private IMessageNotifyRecordService messageNotifyRecordService;

    @Autowired
    private IPatientQueueSchemeDAO patientQueueSchemeDao;

    @Autowired
    private IDepartmentBasicService departmentBasicService;

    /**
     * 待备乳管理->备乳录入。
     * @param reqDTO
     * @param request
     * @return
     * @throws Exception
     * 备注：根据NCIA-6的需求处理：待备乳管理--备乳录入界面：同一个人，一天内允许多次设置待备乳量和备注的信息。
     */
    @Override
    public Map<String, Object> milkPrepPatientPage(MilkPreparationRecordUserPageReqDTO reqDTO, HttpServletRequest request) throws Exception {
        Map<String, Object> sessionMap = ToolUtils.getSessionInfo(request);
        HashMap<String, Object> paramMap = Dict.parse(reqDTO);
        Integer  currentPage= reqDTO.getCurrentPage() == null ? 1 : reqDTO.getCurrentPage();
        Integer  pageSize = reqDTO.getPageSize() == null ? 10 : reqDTO.getPageSize();
        paramMap.put("tenantId", sessionMap.get("tenantId"));
        paramMap.put("status","在院");
        //获取今天已经设置的过备乳的用户,剔除这部分用户
        List<String> userIds = new ArrayList<String>();
        //排除复旦租户队列中已经删除的用户
        if(sessionMap.get("tenantId").equals("fddxekyyzzta001")){
            //特殊处理
            HashMap<String, Object> param2Map = MapUtil.newHashMap();
            param2Map.put("userStatus","0");
            param2Map.put("tenantId","fddxekyyzzta001");
            List<PatientQueueScheme> patientQueueSchemes = patientQueueSchemeDao.selectPatientByCondition(param2Map);
            if(CollUtil.isNotEmpty(patientQueueSchemes)){
                List<String> userIdTempIds = patientQueueSchemes.stream().map(PatientQueueScheme::getUserId).collect(Collectors.toList());
                userIds.addAll(userIdTempIds);
            }
        }
        paramMap.put("notIds",userIds);
        //特殊排序标记1:特殊列表
        paramMap.put("listType",1);
        PageHelper.startPage(currentPage, pageSize);
        List<PatientListBO> patientList = patientDao.selectList(paramMap);
        PageInfo<PatientListBO> page = new PageInfo<>(patientList);
        HashMap<String, Object> responseMap = MapUtil.newHashMap();
        responseMap.put("data", patientList);
        responseMap.put("count", patientList.size());
        return responseMap;
    }

    /**
     * 查询备乳录入列表，每个患者携带当日备乳设置次数字段。
     * @param reqDTO
     * @param request
     * @return
     * @throws Exception
     * Updated by Michael on 2022/07/29.
     */
    public Map<String, Object> milkPrepPatientPageWithCount(MilkPreparationRecordUserPageReqDTO reqDTO, HttpServletRequest request) throws Exception {
        final Map<String, Object> sessionMap = ToolUtils.getSessionInfo(request);
        final String tenantId   = sessionMap.get("tenantId").toString();
        HashMap<String, Object> paramMap = Dict.parse(reqDTO);
        Integer  currentPage= reqDTO.getCurrentPage() == null ? 1 : reqDTO.getCurrentPage();
        Integer  pageSize = reqDTO.getPageSize() == null ? 10 : reqDTO.getPageSize();
        paramMap.put("tenantId", tenantId);
        paramMap.put("status","在院");
        List<PatientListBO> patientList = patientDao.selectMilkPreparation(paramMap);
        final int totalSize = patientList.size();
        logger.info("++++milkPrepPatientPageWithCount2() patientList size:"+totalSize);
        List<FuMilkPreparationRecord> countList = fuMilkPreparationRecordDAO.selectMilkPrepareCount();
        logger.info("++++milkPrepPatientPageWithCount2() countList size:"+countList.size());
        //这里还需要统计每个患者的备乳设置次数。
        String patientUserId,countUserId;
        for(PatientListBO patient : patientList)    {
            patientUserId = patient.getId();
            if (null==patientUserId)    continue;
            for(FuMilkPreparationRecord count : countList)   {
                countUserId = count.getUserId();
                if (null==countUserId)  continue;
                if (count.getUserId().equalsIgnoreCase(patientUserId)) {
                    patient.setMilkPrepareCount(count.getMilkPrepareCount());
                    break;
                }
            }
        }

        //空的床号改成“未填写”放在最后；加床放在中间。
        Collections.sort(patientList, new MilkPatientComparator());
        for(PatientListBO patient : patientList)   {
            if (patient.getHospitalBedNo().equals("0")) {
                patient.setHospitalBedNo("未填写");
            }
        }

        int fromIndex = (currentPage-1) * pageSize;
        int toIndex = fromIndex + pageSize;
        if (toIndex>totalSize)  {
            toIndex = totalSize;
        }
        List<PatientListBO> subPageList = patientList.subList(fromIndex, toIndex);

        HashMap<String, Object> responseMap = MapUtil.newHashMap();
        responseMap.put("data", subPageList);
        responseMap.put("count",totalSize);
        return responseMap;
    }

    @Override
    public int deleteByPK(final String id) {
        return this.fuMilkPreparationRecordDAO.deleteByPrimaryKey(id);
    }

    /**
     * 待备乳管理->备乳录入->设置待备乳量。
     * @param reqDTO
     * @param request
     * @return
     * 备注：允许一天设置多次。
     * updated by Michael on 2022/07.
     */
    @Override
    @Transactional
    public String setMilkQuantity(MilkPreparationSetReqDTO reqDTO, HttpServletRequest request) {
        Map<String, Object> sessionMap = ToolUtils.getSessionInfo(request);
        FuMilkPreparationRecord fuMilkPreparationRecord = new FuMilkPreparationRecord();
        BeanUtil.copyProperties(reqDTO,fuMilkPreparationRecord);
        fuMilkPreparationRecord.setId(IdUtil.getSnowflake(1,1).nextIdStr());
        fuMilkPreparationRecord.setCreaterId(sessionMap.get("authorId").toString());
        fuMilkPreparationRecord.setCreater(sessionMap.get("authorName").toString());
        fuMilkPreparationRecord.setCreateTime(DateUtil.date());
        fuMilkPreparationRecord.setUpdateTime(DateUtil.date());
        fuMilkPreparationRecord.setRecordTime(DateUtil.date());
        //待发送
        fuMilkPreparationRecord.setStatus(1);
        fuMilkPreparationRecord.setSendTime(null);
        if(fuMilkPreparationRecordDAO.insert(fuMilkPreparationRecord)<=0){
           throw new AppException("1001","设置失败");
        }
        return fuMilkPreparationRecord.getId();
    }

    @Override
    public Map<String, Object> listPage(MilkPreparationRecordPageReqDTO reqDTO, HttpServletRequest request) {
        Map<String, Object> sessionMap = ToolUtils.getSessionInfo(request);
        Integer  currentPage= reqDTO.getCurrentPage() == null ? 1 : reqDTO.getCurrentPage();
        Integer  pageSize = reqDTO.getPageSize() == null ? 10 : reqDTO.getPageSize();
        HashMap<String, Object> paramMap = Dict.parse(reqDTO);
        paramMap.put("tenantId", sessionMap.get("tenantId"));
        if(reqDTO.getType()==1){
            paramMap.put("status",1);
        }
        if(reqDTO.getType()==2){
            paramMap.put("status",2);
        }
        //特殊排序标记1:特殊列表
        paramMap.put("listType",1);
        PageHelper.startPage(currentPage, pageSize);
        List<FuMilkPreparationRecord> list = fuMilkPreparationRecordDAO.selectList(paramMap);
        PageInfo<FuMilkPreparationRecord> page = new PageInfo<>(list);
        HashMap<String, Object> responseMap = MapUtil.newHashMap();
        responseMap.put("data", list);
        responseMap.put("count", page.getTotal());
        return responseMap;
    }

    @Override
    public Map<String, Object> sendHistoryPage(MilkPreparationHistoryPageReqDTO reqDTO, HttpServletRequest request) {
        Map<String, Object> sessionMap = ToolUtils.getSessionInfo(request);
        Integer  currentPage= reqDTO.getCurrentPage() == null ? 1 : reqDTO.getCurrentPage();
        Integer  pageSize = reqDTO.getPageSize() == null ? 10 : reqDTO.getPageSize();
        HashMap<String, Object> paramMap = Dict.parse(reqDTO);
        paramMap.put("tenantId", sessionMap.get("tenantId"));
        paramMap.put("status",2);
        paramMap.put("sendTimeStart", DateUtil.parse(DateUtil.format(reqDTO.getSendTime(),"yyyy-MM-dd 00:00:00")));
        paramMap.put("sendTimeEnd", DateUtil.parse(DateUtil.format(reqDTO.getSendTime(),"yyyy-MM-dd 23:59:59")));
        //特殊排序标记1:特殊列表
        paramMap.put("listType",1);
        PageHelper.startPage(currentPage, pageSize);
        List<FuMilkPreparationRecord> list = fuMilkPreparationRecordDAO.selectListOfUserId(paramMap);
        PageInfo<FuMilkPreparationRecord> page = new PageInfo<>(list);
        HashMap<String, Object> responseMap = MapUtil.newHashMap();
        responseMap.put("data", list);
        responseMap.put("count", page.getTotal());
        return responseMap;
    }

    @Override
    public void confirmSend(MilkPreparationChoiceReqDTO reqDTO, HttpServletRequest request) throws Exception {

        Map<String, Object> sessionMap = ToolUtils.getSessionInfo(request);
        String deptId = (String) sessionMap.get("deptId");
        String platType = departmentBasicService.getDepartmentBasicDetails(deptId).getPlatType();

        if(CollUtil.isEmpty(reqDTO.getIds())){
            throw new AppException("1001","请选择");
        }
        List<FuMilkPreparationRecord> fuMilkPreparationRecords = fuMilkPreparationRecordDAO.selectByIds(reqDTO.getIds());
        if(CollUtil.isEmpty(fuMilkPreparationRecords)){
            throw new AppException("1001","记录不存在");
        }
        //只发送未发送的
        List<FuMilkPreparationRecord> noSendMilkRecords = fuMilkPreparationRecords.stream().filter(e -> e.getStatus() == 1).collect(Collectors.toList());
        if(CollUtil.isEmpty(noSendMilkRecords)){
            throw new AppException("1001","发送失败");
        }
        //调用消息接口发送消息
        for (FuMilkPreparationRecord noSendMilkRecord : noSendMilkRecords) {
            messageNotifyRecordService.sendMilkPreparationMessage(noSendMilkRecord, platType);
            FuMilkPreparationRecord fuMilkPreparationRecord = new FuMilkPreparationRecord();
            fuMilkPreparationRecord.setId(noSendMilkRecord.getId());
            //已发送
            fuMilkPreparationRecord.setStatus(2);
            fuMilkPreparationRecord.setSendTime(DateUtil.date());
            fuMilkPreparationRecord.setUpdateTime(DateUtil.date());
            fuMilkPreparationRecordDAO.updateByPrimaryKeySelective(fuMilkPreparationRecord);
        }
    }

    @Override
    public FuMilkPreparationRecordResDTO selectOne(String id) {
        FuMilkPreparationRecord fuMilkPreparationRecord = fuMilkPreparationRecordDAO.selectByPrimaryKey(id);
        FuMilkPreparationRecordResDTO resDTO = new FuMilkPreparationRecordResDTO();
        BeanUtils.copyProperties(fuMilkPreparationRecord,resDTO);
        return resDTO;
    }
}
